/**
 * 
 */
package com.pxingg.encrypt.crc;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author Administrator
 * 
 */
public class CRC
{
    /**
     * The log of this class
     */
    static Log log = LogFactory.getLog(CRC.class);

    /**
     * Optimized Dallas (now Maxim) iButton 8-bit CRC calculation.<br>
     * 
     * Polynomial: x^8 + x^5 + x^4 + 1 (0x8C)<br>
     * Initial value: 0x0<br>
     * 
     * 从AVR libC的函数 _crc_ibutton_update修改得到
     * 
     * @param data
     *            需要计算校验和的消息
     * @param length
     *            需要计算校验和的消息长度
     * @return 计算出来的校验和
     */
    public static byte iButtonCRC8(final byte[] data, final int length)
    {
        int crc = 0x00;

        for (int i = 0; i < length; i++)
        {
            crc = crc ^ data[i];
            for (int k = 0; k < 8; k++)
            {
                if ((crc & 0x01) > 0)
                {
                    crc = (crc >> 1) ^ 0x8C;
                }
                else
                {
                    crc >>= 1;
                }
            }
        }

        return (byte) crc;
    }

    /**
     * 计算出字节的和，保留一个结果的最后一个字节
     * 
     * @param data
     *            需要计算校验和的消息
     * @param length
     *            需要计算校验和的消息长度
     * @return 计算出来的校验和
     */
    public static byte sumCRC8(final byte[] data, final int length)
    {
        byte crc = (byte) 0x00;
        for (int i = 0; i < length; i++)
        {
            crc += data[i];
        }

        return crc;
    }
}
